package com.grm.demo.semaphore;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class MySemaphore {
    static class Pool {
        // 限制数
        private static final int MAX_AVAILABLE = 6;
        private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
        public Object getItem() throws InterruptedException {
            // 加锁
            available.acquire();
            // 获取下一个存活的元素
            return getNextAvailableItem();
        }
        public void putItem(Object x) {
            if (markAsUnused(x))
                // 解锁
                available.release();
        }
        protected Object[] items;
        protected boolean[] used = new boolean[MAX_AVAILABLE];
        Pool() {
            items = new Object[15];
            for (int i = 0; i < items.length; i++) {
                items[i] = "item" + i;
            }
        }
        protected synchronized Object getNextAvailableItem() {
            for (int i = 0; i < MAX_AVAILABLE; ++i) {
                if (!used[i]) {
                    used[i] = true;
                    return items[i];
                }
            }
            return null; // not reached
        }
        protected synchronized boolean markAsUnused(Object item) {
            for (int i = 0; i < MAX_AVAILABLE; ++i) {
                if (item == items[i]) {
                    if (used[i]) {
                        used[i] = false;
                        return true;
                    } else
                        return false;
                }
            }
            return false;
        }
    }
    public static void main(String[] args) {
        final int THREAD_COUNT = 10;
        ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
        Pool pool = new Pool();
        for (int i = 0; i < THREAD_COUNT; i++) {
            int tmpI = i;
            threadPool.submit(() -> {
                try {
                    Object item = pool.getItem();
                    System.out.printf("当前线程:%s,获取到缓存池中的资源:%s\n", Thread.currentThread().getName(), item);
                    Thread.sleep(7);
                    pool.putItem(item);
                    System.out.printf("当前线程:%s,已将缓存池中的资源%s放回池中\n", Thread.currentThread().getName(), item);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        threadPool.shutdown();
    }
}